package com.ruoyi.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.domain.Article;
import com.ruoyi.system.domain.Wechatuser;
import com.ruoyi.system.service.IArticleService;
import com.ruoyi.system.service.IWechatuserService;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.http.HttpType;
import me.chanjar.weixin.mp.api.*;
import me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl;
import me.chanjar.weixin.mp.bean.draft.WxMpDraftArticles;
import me.chanjar.weixin.mp.bean.draft.WxMpDraftItem;
import me.chanjar.weixin.mp.bean.draft.WxMpDraftList;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.material.*;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.soap.SAAJResult;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author binary wang
 */
@RestController
@RequestMapping("/system/wechat")
@SpringBootApplication
public class WechatController {

    private static final Logger log = LoggerFactory.getLogger(WechatController.class);

    @Autowired
    private WxMpService mpService;
    private WxMpMessageRouter messageRouter;
    private String appid;
    private String menuId = null;

    @Autowired
    private IArticleService articleService;
    @Autowired
    private IWechatuserService wechatuserService;

    public WechatController() {
        this.appid = "wx9bf99f0efd355c8f";
    }

    @GetMapping(produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {

        log.info("\n接收到来自微信服务器的认证消息：[{}, {}, {}, {}]", signature,
                timestamp, nonce, echostr);
        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法，请核实!");
        }

        if (!this.mpService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }

        if (mpService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法请求";
    }

    @GetMapping("/check1")
    public String checkSign(HttpServletRequest request)
    {
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String signature = request.getParameter("signature");
        String echostr = request.getParameter("echostr");

        log.error("timestamp------------------" + timestamp);
        log.error("nonce------------------" + nonce);
        log.error("signature------------------" + signature);

        log.error("this.mpService.checkSignature(timestamp, nonce, signature)------------------" + this.mpService.checkSignature(timestamp, nonce, signature));

        if (this.mpService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        } else {
            return "非法请求";
        }
    }

    @GetMapping("/test")
    public String test() throws WxErrorException {
        String appid = this.mpService.getWxMpConfigStorage().getAppId();
        return appid;
    }

    //接收消息
    private WxMpXmlMessage receive(HttpServletRequest request, HttpServletResponse response, String expected) throws ServletException, IOException {
        String signature = request.getParameter("signature");
        String nonce = request.getParameter("nonce");
        String timestamp = request.getParameter("timestamp");

//        response.setContentType("text/html;charset=utf-8");
//        response.setStatus(HttpServletResponse.SC_OK);

        if (!mpService.checkSignature(timestamp, nonce, signature)) {
            // 消息签名不正确，说明不是公众平台发过来的消息
            response.getWriter().println("非法请求");
            return null;
        }

        String echostr = request.getParameter("echostr");
        if (StringUtils.isNotBlank(echostr)) {
            // 说明是一个仅仅用来验证的请求，回显echostr
            response.getWriter().println(echostr);
            return null;
        }

        String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ?
                "raw" :
                request.getParameter("encrypt_type");

        WxMpXmlMessage message = null;

        if ("raw".equals(encryptType)) {
            // 明文传输的消息
            message = WxMpXmlMessage.fromXml(request.getInputStream());
        } else if ("aes".equals(encryptType)) {
            // 是aes加密的消息
            String msgSignature = request.getParameter("msg_signature");
            message = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), mpService.getWxMpConfigStorage(), timestamp, nonce, msgSignature);
        } else {
            response.getWriter().println("不可识别的加密类型");
            return null;
        }
        return message;
    }

    //获取关键词<==>消息列表
    private List<Article> getAticles() {
        Article article = new Article();
        List<Article> list = articleService.selectArticleList(article);
        return list;
    }

    //回复消息
    @RequestMapping("/check")
    public void reply(HttpServletRequest request, HttpServletResponse response, String expected) throws ServletException, IOException, WxErrorException {

        response.setContentType("text/xml;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);

        //创建菜单
//        this.createMenu();

        //接收消息
        WxMpXmlMessage message = receive(request, response, expected);

        //消息处理
        String messageType=message.getMsgType();   //消息类型
        String fromUser=message.getFromUser();
        String touser=message.getToUser();
        String content=message.getContent();
        String evnt = message.getEvent();
        log.error("------------content" + content);
        log.error("------------event" + evnt);
        log.error("------------fromUser" + fromUser);
        log.error("------------touser" + touser);

        WxMpXmlOutMessage news = null;

        if (evnt != null && evnt.equals("subscribe")) {
            Wechatuser weUser = new Wechatuser();
            String tMsg = "";
            weUser.setOpenid(fromUser);
            List<Wechatuser> weUsers = wechatuserService.selectWechatuserList(weUser);
            String nickname = this.saveUser(fromUser);
            if (weUsers.size() == 1) {
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                String dates = "";
                for (Wechatuser user: weUsers) {
                    dates = dates + dateFormat.format(Long.parseLong(user.getSubTime()));
                }

                tMsg = "您已于" + dates + "关注过我们，欢迎再次关注！";
            } else if (weUsers.size() > 1) {
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                String dates = "";
                int i = 0;
                for (Wechatuser user: weUsers) {
                    if (i+1 == weUsers.size()) {
                        dates = dates + "                  " + dateFormat.format(Long.parseLong(user.getSubTime())) + "\r\n";;
                    } else if (i == 0) {
                        dates = dates + dateFormat.format(Long.parseLong(user.getSubTime())) + ",\r\n";
                    } else {
                        dates = dates + "                  " + dateFormat.format(Long.parseLong(user.getSubTime())) + ",\r\n";
                    }
                    i++;
                }

                tMsg = "您分别于" + dates + "关注过我们，欢迎再次关注！";
            } else {
                System.out.println("保存用户信息========");
                tMsg = nickname +"您好！欢迎关注我们！";
            }
            System.out.println("关注回复文本消息========");
            //创建消息文本
            news=WxMpXmlOutTextMessage.TEXT().toUser(fromUser).fromUser(touser).content(tMsg).build();

            //执行发送
            String xml=news.toXml();
            PrintWriter out=null;
            try {
                out = response.getWriter();
                out.print(xml);
            } catch (IOException e) {
                out.close();
                out=null;
                e.printStackTrace();
            }
            out.close();
            out=null;
        } else {
            System.out.println("收到用户发送的消息关键词自动回复========");
            if (content != null) {
                List<Article> articles = getAticles();
                for (Article article: articles) {
                    log.info("------article-------:" + article.toString());
                    //文本消息
                    if(content.equals(article.getKeyword())){
                        if (StringUtils.isNotBlank(article.getNewsTitle())) {
                            System.out.println("图文消息========");
                            WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
                            item.setDescription(article.getNewsDesc());
                            item.setPicUrl(article.getNewsPicurl());
                            item.setTitle(article.getNewsTitle());
                            item.setUrl(article.getNewsUrl());

                            news = WxMpXmlOutMessage.NEWS()
                                    .fromUser(touser)
                                    .toUser(fromUser)
                                    .addArticle(item)
                                    .build();

                            //发送客服文本消息
                            WxMpKefuMessage textMessage = WxMpKefuMessage
                                    .TEXT()
                                    .toUser(fromUser)
                                    .content(article.getMessage())
                                    .build();
                            this.mpService.getKefuService().sendKefuMessage(textMessage);

                            //执行发送
                            String xml=news.toXml();
                            PrintWriter out=null;
                            try {
                                out = response.getWriter();
                                out.print(xml);
                            } catch (IOException e) {
                                out.close();
                                out=null;
                                e.printStackTrace();
                            }
                            out.close();
                            out=null;

                        } else {
                            System.out.println("文本消息========");
                            //创建消息文本
                            news=WxMpXmlOutTextMessage.TEXT().toUser(fromUser).fromUser(touser).content(article.getMessage()).build();

                            //执行发送
                            String xml=news.toXml();
                            PrintWriter out=null;
                            try {
                                out = response.getWriter();
                                out.print(xml);
                            } catch (IOException e) {
                                out.close();
                                out=null;
                                e.printStackTrace();
                            }
                            out.close();
                            out=null;
                        }
                        log.error("------------------门卫-------------------："+ article.getType());
                        if (StringUtils.isNotBlank(article.getType())) {
                            if (article.getType().equals("video")) {
                                log.error("------------------门内-------------------："+ article.getType());
                                try {
                                    WxMpKefuMessage videoMessage = WxMpKefuMessage
                                            .VIDEO()
                                            .toUser(fromUser)
                                            .mediaId(article.getFilesMediaid())
                                            .description("")
                                            .build();
                                    boolean res = this.mpService.getKefuService().sendKefuMessage(videoMessage);
                                    log.error("------------------res-------------------："+ res);
                                } catch (Exception er) {
                                    log.error("------------------er-------------------："+ er.getMessage());
                                }

                            } else if (article.getType().equals("voice")) {
                                log.error("------------------门内2-------------------："+ article.getType());
                                try {
                                    WxMpKefuMessage voiceMessage = WxMpKefuMessage
                                            .VOICE()
                                            .toUser(fromUser)
                                            .mediaId(article.getFilesMediaid())
                                            .build();
                                    boolean res = this.mpService.getKefuService().sendKefuMessage(voiceMessage);
                                    log.error("------------------res-------------------："+ res);
                                } catch (Exception er) {
                                    log.error("------------------er-------------------："+ er.getMessage());
                                }

                            } else if (article.getType().equals("image")) {
                                log.error("------------------门内3-------------------："+ article.getType());
                                try {
                                    WxMpKefuMessage imageMessage = WxMpKefuMessage
                                            .IMAGE()
                                            .toUser(fromUser)
                                            .mediaId(article.getFilesMediaid())
                                            .build();
                                    boolean res = this.mpService.getKefuService().sendKefuMessage(imageMessage);
                                    log.error("------------------res-------------------："+ res);
                                } catch (Exception er) {
                                    log.error("------------------er-------------------："+ er.getMessage());
                                }

                            }
                        }
                        break;
                    } else {
                        System.out.println("没找到该关键词");
                    }
                }
            }
        }

//        if (news != null) {
//            String xml=news.toXml();
//            PrintWriter out=null;
//            try {
//                out = response.getWriter();
//                out.print(xml);
//            } catch (IOException e) {
//                out.close();
//                out=null;
//                e.printStackTrace();
//            }
//            out.close();
//            out=null;
//        } else {
//            System.out.println("news == null");
//        }
    }

    //保存用户信息
    private String saveUser(String fromUser) {
        String lang = "zh_CN"; //语言
        WxMpUser user = null;
        try {
            System.out.println("获取用户信息========");
            user = this.mpService.getUserService().userInfo(fromUser,lang);

            Wechatuser wechatuser = new Wechatuser();
            wechatuser.setNickname(user.getNickname().replaceAll("[\\x{10000}-\\x{10FFFF}]", ""));
            wechatuser.setOpenid(user.getOpenId());
//            wechatuser.setSex(user.getSex());
//            wechatuser.setCity(user.getCity());
//            wechatuser.setProvince(user.getProvince());
//            wechatuser.setCountry(user.getCountry());
            Long time = new Date().getTime();
            wechatuser.setSubTime(time.toString());
            Integer res = wechatuserService.insertWechatuser(wechatuser);
            log.info("-------------保存用户信息结果-----------" + res);

        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        return user.getNickname();
    }

    //自定义菜单
    private void createMenu() throws WxErrorException {
        String json = "{\n" +
                " 	\"button\":[\n" +
                " 	{	\n" +
                "    	\"type\":\"view\",\n" +
                "    	\"name\":\"回复设置\",\n" +
                "     	\"url\":\"http://branch.zhiyu.store/\" \n" +
                "	},\n" +
                " 	{	\n" +
                "    	\"type\":\"view\",\n" +
                "    	\"name\":\"精彩文章\",\n" +
                "     	\"url\":\"https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=Mzg3ODU3ODExOA==&scene=124#wechat_redirect\" \n" +
//                "     	\"url\":\"https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzkwNjIxNjE3Ng==&scene=124#wechat_redirect\" \n" +
                "	},\n" +
                " 	{	\n" +
                "    	\"type\":\"view\",\n" +
                "    	\"name\":\"联系我们\",\n" +
                "     	\"url\":\"http://mp.weixin.qq.com/s?__biz=Mzg3ODU3ODExOA==&mid=100000240&idx=1&sn=b78d449d65cff9bea8303109f1677f5a&chksm=4f10d1597867584ffab19543490b12fc4c0601fec7470aabec8eca923431b880048690009f7c&scene=18#wechat_redirect/\" \n" +
                "	}\n" +
                "]\n" +
                "}";
        this.mpService.getMenuService().menuCreate(json);
    }

    //获取图文素材列表
//    @RequestMapping(value = "/news", method = RequestMethod.GET)
//    public AjaxResult getNewsList(@RequestParam(name = "page", required = true) Integer page, @RequestParam(name = "psize", required = true) Integer psize, @RequestParam(name = "keyword", required = false) String keyword) throws WxErrorException {
//        WxMpMaterialNewsBatchGetResult wxMpMaterialNewsBatchGetResult = this.mpService.getMaterialService().materialNewsBatchGet(page*psize, psize);
//        log.error("wxMpMaterialNewsBatchGetResult.getTotalCount:" + wxMpMaterialNewsBatchGetResult.getTotalCount());
//        log.error("---------------------------------------------");
//        List<WxMpMaterialNewsBatchGetResult.WxMaterialNewsBatchGetNewsItem> newsItems = wxMpMaterialNewsBatchGetResult.getItems();
//        List<WxMpNewsArticle> titles = new ArrayList<WxMpNewsArticle>();
//        log.error("=========keyword=============:" + keyword);
//        newsItems.forEach(item -> {
//            if (StringUtils.isNotBlank(keyword)) {
//                WxMpNewsArticle art = item.getContent().getArticles().get(0);
//                if (art.getTitle().contains(keyword)) {
//                    titles.add(art);
//                }
//            } else {
//                titles.add(item.getContent().getArticles().get(0));
//            }
//        });
//        JSONObject json = new JSONObject();
//        json.put("data", titles);
//        json.put("total", wxMpMaterialNewsBatchGetResult.getTotalCount());
//        return AjaxResult.success(json);
//    }

    //获取草稿和历史图文素材列表
    @RequestMapping(value = "/news", method = RequestMethod.GET)
    public AjaxResult getDraftsList(@RequestParam(name = "page", required = true) Integer page, @RequestParam(name = "psize", required = true) Integer psize, @RequestParam(name = "keyword", required = false) String keyword) throws WxErrorException {
        //图文素材
        WxMpMaterialNewsBatchGetResult wxMpMaterialNewsBatchGetResult = this.mpService.getMaterialService().materialNewsBatchGet(page*psize, psize);
        List<WxMpMaterialNewsBatchGetResult.WxMaterialNewsBatchGetNewsItem> newsItems = wxMpMaterialNewsBatchGetResult.getItems();
        List<WxMpNewsArticle> titles = new ArrayList<WxMpNewsArticle>();
        newsItems.forEach(item -> {
            if (StringUtils.isNotBlank(keyword)) {
                WxMpNewsArticle art = item.getContent().getArticles().get(0);
                if (art.getTitle().contains(keyword)) {
                    titles.add(art);
                }
            } else {
                titles.add(item.getContent().getArticles().get(0));
            }
        });
        JSONObject json = new JSONObject();
        json.put("data", titles);
        json.put("total", wxMpMaterialNewsBatchGetResult.getTotalCount());
        log.error("wxMpMaterialNewsBatchGetResult.getTotalCount:" + wxMpMaterialNewsBatchGetResult.getTotalCount());
        log.error("---------------------------------------------");
        //草稿素材
        WxMpDraftList draftList = this.mpService.getDraftService().listDraft(page*psize, psize);
        log.error("draftList.getTotalCount:" + draftList.getTotalCount());
        log.error("---------------------------------------------");
        List<WxMpDraftItem> newsItems2 = draftList.getItems();
        List<WxMpDraftArticles> titles2 = new ArrayList<WxMpDraftArticles>();
        newsItems2.forEach(item -> {
            titles2.add(item.getContent().getNewsItem().get(0));
        });
        log.error("22222222222222222222222222222222222222");
        log.error("titles2.toString():" + titles2.toString());

        json.put("data2", titles2);
        json.put("total2", draftList.getTotalCount());
        return AjaxResult.success(json);
    }

    //获取非图文素材列表
    @RequestMapping(value = "/files", method = RequestMethod.GET)
    public AjaxResult getFilesList(@RequestParam(name = "page", required = true) Integer page, @RequestParam(name = "psize", required = true) Integer psize, @RequestParam(name = "type", required = true) String type) throws WxErrorException {
        WxMpMaterialFileBatchGetResult wxMpMaterialFilesBatchGetResult = this.mpService.getMaterialService().materialFileBatchGet(type, page*psize, psize);
        log.error("wxMpMaterialNewsBatchGetResult.getTotalCount:" + wxMpMaterialFilesBatchGetResult.getTotalCount());
        log.error("---------------------------------------------");
        List<WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem> filesItems = wxMpMaterialFilesBatchGetResult.getItems();
//        List<WxMpNewsArticle> titles = new ArrayList<WxMpNewsArticle>();
//        newsItems.forEach(item -> {
//            titles.add(item.getContent().getArticles().get(0));
//        });
        JSONObject json = new JSONObject();
        json.put("data", filesItems);
        json.put("total", wxMpMaterialFilesBatchGetResult.getTotalCount());
        return AjaxResult.success(json);
    }

    //获取图文素材列表
    public void sendKfmsg() throws WxErrorException {


    }

    //获取单个图文素材
    private void getNews(String mediaId) throws WxErrorException {
        WxMpMaterialNews wxMpMaterialNewsSingle = this.mpService
                .getMaterialService().materialNewsInfo(mediaId);

        System.out.println(wxMpMaterialNewsSingle);
    }
}
